-
Notifications
You must be signed in to change notification settings - Fork 193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lemma 5.8.2. from the book #2143
base: master
Are you sure you want to change the base?
Conversation
It might be a day or two before I can look at this closely. I'd be very surprised if you can prove (ii) without funext. To show a function type is contractible, you have to prove that two functions are equal, which will require funext. (It's even needed to show Will using Pointed simplify things significantly, or just slightly? (And presumably you meant Pointed.Core?) I agree that requiring Pointed.Core would bring in way too many dependencies for this file. So if it wouldn't simplify things too much, then maybe it's ok as is? About the overall structure: the proof of (ii) => (iii) seems the hardest. Is it easier to replace it with (ii) => something else, since we know the others are equivalent? (And is it worth dropping any redundant implications? I think it's ok keeping redundant ones if the proofs are short.) Let's use (ii) rather than ii) consistently. For the proof that's embedded in HoTTBook.v, maybe it should be put in PathAny.v, since someone will likely look there for the various implications. |
@@ -1,4 +1,5 @@ | |||
Require Import Basics Types. | |||
Require Import HoTT.Tactics. | |||
|
|||
(** A nice method for proving characterizations of path-types of nested sigma-types, due to Rijke. *) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is a bit odd, since the method is much more general than nested sigma types. How about completely replacing it with a sentence saying that this file gives several characterizations of path types, following Theorem 5.8.2 in the book. And move the comment about EncodeDecode to this spot too.
Co-authored-by: Dan Christensen <[email protected]>
Co-authored-by: Dan Christensen <[email protected]>
Co-authored-by: Dan Christensen <[email protected]>
It looks like I hallucinated. I believed that
I tried to prove (ii) => (iv), but I wasn't able to do it. Those two statements seem very close to each other, so I felt like there would be an obvious translation... However, the technique used in (ii) => (iii) should be adaptable to (ii) => (i). Regarding the implication logic. Since I don't want the whole result to depend on funext, I only want to first prove (i) <=> (iii) <=> (iv). Afterwards we may assume funext to then say that (ii) is logically equivalent. We already have (i) <=> (iii) <=> (iv), and the proofs are pretty short. We will only save 1 implication if we have a smart route through, so I don't think it matters too much 🤷♀️ |
I wonder if it would be helpful to state a funext-free version of (ii), namely that any two maps in the type under consideration are homotopic (in a sense that respects the pointedness). If we call this (ii'), then we could have cyclic implications involving (i), (ii'), (iii) and (iv), and then separately have (ii) <=> (ii'), using funext. (But, as I said, I don't care too much about minimizing the number of implications when there are short proofs. The motivation here is more that it might clean up (i) => (ii) and (ii) => (iii) to factor them through (ii').) |
I would lean on the side of not introducing Regarding funext, here is how to drop it: Definition pathpfammap {A : Type} {a0 : A} {R S : A -> Type} {r0 : R a0} {s0 : S a0}
(f g : pfammap R S r0 s0) : Type
:= { p : forall a : A, f.1 a == g.1 a & p a0 r0 = f.2 @ g.2^}.
Definition homocontr_pfammap_identitysystem `{Funext} {A : Type} {a0 : A}
(R : A -> Type) (r0 : R a0) `{!IsIdentitySystem R r0} (S : A -> Type) (s0 : S a0)
: exists f : pfammap R S r0 s0, forall g, pathpfammap f g.
Proof.
pose (f := IdentitySystem_ind (fun a _ => S a) s0).
pose proof (f0 := IdentitySystem_ind_beta (fun a _ => S a) s0).
snrefine ((f; f0); _).
intro g; cbn.
exists (IdentitySystem_ind (fun a r => f a r = g.1 a r) (f0 @ g.2^)).
snrapply IdentitySystem_ind_beta.
Defined . We do a similar trick in many other places. Contractibility as asked for in the HoTT book, becomes a corollary of |
By the way, the proof of The reason I believe it can be eliminated is because you |
Great! Now, what do you usually name mapping spaces in the library? Taking inspiration from Pointed.Core, I think the best thing would be to call these spaces for
Do you think it can be easier to do another direction? If (ii) => (i) is easier to do, then we can maybe change the original structure to get a simpler proof. Anyways, if we get (ii) => (i) then we have enough to state the theorem. |
I think this direction still works, but should introduce some more general lemmas. Part of the confusion is that Let's come back to this point in a bit. Firstly I want to show a more symmetrical lemma that will be useful: Definition isequiv_identitysystem_ind {A : Type} {a0 : A}
(R : A -> Type) (r0 : R a0) `{!IsIdentitySystem R r0}
(S : A -> Type) (s0 : S a0) `{!IsIdentitySystem S s0}
: forall (a : A), IsEquiv (IdentitySystem_ind (R:=R) (fun a' _ => S a') s0 a).
Proof.
intros a.
snrapply isequiv_adjointify.
- exact (IdentitySystem_ind (R:=S) (fun a' _ => R a') r0 a).
- revert a.
rapply (IdentitySystem_ind (R:=S)).
lhs nrapply ap.
1: snrapply IdentitySystem_ind_beta.
nrapply IdentitySystem_ind_beta.
- revert a.
rapply (IdentitySystem_ind (R:=R)).
lhs nrapply ap.
1: snrapply IdentitySystem_ind_beta.
nrapply IdentitySystem_ind_beta.
Defined. The proof is symmetric, but I didn't bother condensing it down further. It can probably be done in half the lines. This general lemma will specialise accordingly without having to treat paths as a special case every time. Next we have this quite important instance: Global Instance isidentitysystem_paths {A : Type} {a0 : A}
: IsIdentitySystem (paths a0) idpath.
Proof.
snrapply Build_IsIdentitySystem.
- nrapply paths_ind.
- reflexivity.
Defined. This makes the proof of (** Given an identity system, transporting the point [r0] induces a fiber-wise equivalence between the based path type on [a0] and [R]. This is Theorem 5.8.2 (i) => (iii) from the Book. *)
Global Instance isequiv_transport_IsIdentitySystem {A : Type} {a0 : A}
(R : A -> Type) (r0 : R a0) `{!IsIdentitySystem R r0}
(a : A) : IsEquiv (fun p : a0 = a => transport R p r0).
Proof.
exact (isequiv_identitysystem_ind (paths a0) idpath R r0 a).
Defined. What we are doing with We have identity maps and composition: Definition pfammap_compose {A : Type} {a0 : A} {R S T : A -> Type} {r0 : R a0} {s0 : S a0} {t0 : T a0}
: pfammap S T s0 t0 -> pfammap R S r0 s0 -> pfammap R T r0 t0.
Proof.
intros [f Hf] [g Hg].
exists (fun a r => f a (g a r)).
exact (ap (f _) Hg @ Hf).
Defined.
Definition pfammap_id {A : Type} {a0 : A} {R : A -> Type} {r0 : R a0}
: pfammap R R r0 r0.
Proof.
exists (fun a r => r).
reflexivity.
Defined. this lets us state the more general lemma: Definition isidentitysystem_pathpfammap {A : Type} {a0 : A}
(R : A -> Type) (r0 : R a0) (S : A -> Type) s0
(f : pfammap R S r0 s0)
(g : pfammap S R s0 r0)
(f_g : pathpfammap (pfammap_compose f g) pfammap_id)
(g_f : pathpfammap (pfammap_compose g f) pfammap_id)
: IsIdentitySystem R r0 -> IsIdentitySystem S s0.
Proof.
intros H.
snrapply Build_IsIdentitySystem.
- intros P P1.
intros a r.
pose ((f_g).1 a r) as p.
cbn in p.
refine (p # _).
set (g.1 a r) as x.
change (P a (f.1 a x)).
clearbody x; clear r p; revert a x.
rapply IdentitySystem_ind.
refine (_^ # P1).
exact f.2.
- intros P P1; cbn.
Admitted. which states that the property of being an identity system is invariant under equivalences in the wild category of pointed families. I didn't finish this quite, but I'm fairly certain it can be done. The final path induction is complicated and needs a clever set up since Coq is too dumb to generalise variables. Anyway, with that you should have: Global Instance equiv_path_contr_pfammap {A : Type} {a0 : A} (R : A -> Type) (r0 : R a0)
(H : forall S : A -> Type, forall s0 : S a0, exists f : pfammap R S r0 s0, forall g, pathpfammap f g)
(a : A) : IsEquiv (fun p : a0 = a => transport R p r0).
Proof.
snrapply isequiv_transport_IsIdentitySystem.
pose (H (paths a0) idpath) as H'.
srapply isidentitysystem_pathpfammap.
- exists (fun a p => transport R p r0).
reflexivity.
- exact H'.1. and I think this should be doable. Wildcat stuff might help you organize things going on. You can just define |
@Alizter What you wrote sounds nice, but it seems to add a lot. The current form of the PR already has all implications that are needed, so I'm not sure it's worth getting too fancy, or introducing a dependency on wild categories. (OTOH, with wild categories, some of these results are special cases of general facts, e.g. that any two initial objects are equivalent.) My hope in introducing the non-funext version (ii') of (ii) was to end up with shorter proofs, which worked for (i) => (ii'). So all we need is a short proof of (ii') => something, plus (ii') <=> (ii), which should be easy. I think (ii') => (iii) should be straightforward. |
With the new definition, (ii') => (iii) became a lot simpler. I don't really know how to use tactics so well for this, so I would take any advice that cleans up the proof. |
Here is a way to do it with tactics. Proof.
snrapply isequiv_adjointify.
- revert a.
by rapply IdentitySystem_ind.
- hnf; revert a.
rapply IdentitySystem_ind.
apply (ap (fun x => transport R x r0) (y:=1)).
rapply IdentitySystem_ind_beta.
- intros p.
destruct p.
rapply IdentitySystem_ind_beta.
Defined. |
Yes, it ends up being too fancy for its own good that way. @ThomatoTomato seems to have found the proof I was looking for before using this way. All that is left is to clean up the names a bit. I will do another pass in the weekend with some better suggestions. |
When this is ready to merge (but not before then), let's squash many of these commits together. Probably everything until this point can be squashed into one, but if @Alizter makes additional commits, they can be kept separate to keep track of authorship. I can do this once it is ready to merge, if @ThomatoTomato doesn't know how. |
Style comments: The
The file should end in a new line. There's probably more, so please give it a careful read-through. |
(iv) => (i) is pretty short and sweet. I removed (i) => (iii) and factored that one through (ii'). I'm not sure if we should still keep (iv) => (iii) around. It is used a couple of other places in the library. Dan has suggested that we move PathAny.v into the Homotopy subdirectory. I don't know what the file should be called. The contents all resolve around characterizing based path types. |
I was thinking we could rename PathAny.v to Homotopy/IdentitySystems.v. That location puts it right beside Homotopy/EncodeDecode.v, which has similar goals, but more dependencies. @Alizter , what do you think? (I want to get rid of as many things in the top-level theories/ folder as possible.) |
We should keep the statement of (iv) => (iii), since it is useful. The proof could either be kept as is or it could be a composite of the other implications. Since the proof is fairly short and conceptual, maybe just keeping it the current proof is best? If we do, then I think it will be useful to first have the various implications that together prove 5.8.2, possibly via a cyclic ordering, and then record some of the additional implications that are useful, noting that they also follow by composing earlier results. The other lemmas/tactics in the file could come at the end. |
Defined. | ||
|
||
(** The fundamental theorem of identity systems tells us that these four different properties are logically equivalent. *) | ||
Definition FundamentalThmIdentitySystems {A : Type} {a0 : A} (R : A -> Type) (r0 : R a0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's worth stating this result. It's the individual implications that are useful. (For two equivalent things, it's sometimes handy to state an iff version using <->
because we have lemmas about <->
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be possible to write down a general term for "the following are equivalent" which would take a list Type
and conjunct them as a circular implication between elements. To use such a term, we would have a lemma which would take two positions in the original list and produce an implication or iff between them.
Mathcomp does something like this https://github.com/math-comp/math-comp/blob/0240d6c7c46015d333b12889b04acd179224d9d3/mathcomp/ssreflect/seq.v#L4704
(** There are also some additional properties that we can be use to characterize identity types. A pointed type family is an identity system if it satisfies the J-rule. *) | ||
Class IsIdentitySystem {A : Type} {a0 : A} (R : A -> Type) (r0 : R a0) | ||
:= | ||
{ IdentitySystem_ind (D : forall a : A, R a -> Type) (d : D a0 r0) (a : A) (r : R a) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Usually we use capitals in the name of a class or type, but not in the names of other results about that class or type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I should also add that I had some trouble figuring out why some terms were not working, but I later realised my editor had substituted IsIdentitySystem_ind
which is automatically generated from the class.
I would suggest calling this something like idsys_ind
.
:= {f : forall a : A, R a -> S a & f a0 r0 = s0}. | ||
|
||
(** We can also consider pointed homotopies between maps of pointed type families. *) | ||
Definition path_pfamMap {A : Type} {a0 : A} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing about capitalization of pfamMap
.
That sounds sensible. |
In this PR we prove that based identity types are characterized by the J-rule or contractible total spaces. This is the contents of lemma 5.8.2.
Many of the results already exists within the library, and the equivalences i) <=> iii) <=> iv) seems useful to have in its own right. The additions that this PR makes is the following implications: i) => ii), i) => iii), ii) => iii), and iii) => iv).
I'm struggling a little to know how to organize the files. The implications that goes through ii) should depend on Pointed.Basics, but nothing else in PathAny requires Pointed. I think it is best to put this somewhere else. It also seems that i) => ii) requires funext.
I'm also not very happy with all my proofs, so I would gladly take some advice on how to improve them. It should be obvious from the comments were I would like to see some improvements, if there are any good improvements to make.